/**
 * <pre>
 * @(#)BufferView.java 1.00 2009-11-16
 * 
 * Copyright (c) 1998, 2009 Regular Individual. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * Contributor(s):
 *     Haixu Huang
 * </pre>
 **/
package cn.sh.huang.chart.view;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

/**
 * <pre>
 * BufferView ...
 * 
 * @version 1.0
 * </pre>
 */
public abstract class BufferView extends View
{
    private transient Image graph = null;

    protected void doUpdate()
    {
        Dimension viewSize = getViewSize();
        if (graph == null || graph.getWidth(null) != viewSize.width || graph.getHeight(null) != viewSize.height) {
            recycleGraph();
            graph = new BufferedImage(viewSize.width, viewSize.height, BufferedImage.TYPE_INT_ARGB);
            renderBuffer((Graphics2D) graph.getGraphics());
        }
    }

    final private void recycleGraph()
    {
        if (graph != null) {
            graph.getGraphics().dispose();
            graph = null;
            System.gc();
        }
    }

    public void dispose()
    {
        recycleGraph();
        super.dispose();
    }

    /*
     * (non-Javadoc)
     * @see cn.sh.huang.chart.view.AbstractView#render(java.awt.Image)
     */
    public void render(Graphics2D g2d)
    {
        if (graph != null) {
            Point viewAnchor = getViewAnchor();
            Rectangle viewRect = getViewRect();

            int rx = viewRect.x, ry = viewRect.y, rw = viewRect.width, rh = viewRect.height;
            int vx = viewAnchor.x, vy = viewAnchor.y, vw = graph.getWidth(null), vh = graph.getHeight(null);
            if (vx > rx + rw || vx + vw < rx || vy > ry + rh || vy + vh < ry) { // out of rendering area
                return;
            }
            int sx = rx - vx, sy = ry - vy;
            g2d.drawImage(graph, rx, ry, rx + rw, ry + rh, sx, sy, sx + rw, sy + rh, null);
        }
    }

    abstract protected void renderBuffer(Graphics2D g2d);
}
